#include "usr_spi_connection.h"

#include "iot_gpio.h"
#include <stdint-gcc.h>
#include <string.h>

#include "spi.h"
#include "iot_gpio_ex.h"

void spi_init(void)
{
    // 配置引脚功能，将 GPIO 设置为标准 SPI 模式
    IoSetFunc(IOT_IO_NAME_GPIO_6, IOT_IO_FUNC_GPIO_6_SPI1_SCK);    // SCK
    IoSetFunc(IOT_IO_NAME_GPIO_1, IOT_IO_FUNC_GPIO_1_SPI1_IO0_SO); // IO0
    IoSetFunc(IOT_IO_NAME_GPIO_3, IOT_IO_FUNC_GPIO_3_SPI1_IO1_S1); // IO1
    IoSetFunc(IOT_IO_NAME_GPIO_0, IOT_IO_FUNC_GPIO_0_SPI1_CSN);    // CS

    spi_attr_t spi_attr_t_info;
    spi_attr_t_info.is_slave = 0;                                     // 主机模式
    spi_attr_t_info.frame_format = SPI_CFG_FRAME_FORMAT_MOTOROLA_SPI; // Motorola SPI
    spi_attr_t_info.spi_frame_format = HAL_SPI_FRAME_FORMAT_STANDARD; // 标准 SPI 模式
    spi_attr_t_info.tmod = HAL_SPI_TRANS_MODE_TXRX;                   // 全双工传输模式
    spi_attr_t_info.freq_mhz = SPI_FREQUENCY;                         // SPI 频率
    spi_attr_t_info.bus_clk = BUS_CLOCK;                              // SPI 总线时钟
    spi_attr_t_info.clk_polarity = SPI_CFG_CLK_CPOL_0;                // 时钟极性
    spi_attr_t_info.clk_phase = SPI_CFG_CLK_CPHA_0;                   // 时钟相位
    spi_attr_t_info.frame_size = HAL_SPI_FRAME_SIZE_8;                // 帧大小
    spi_attr_t_info.ndf = 0;
    spi_attr_t_info.sste = 0;
    spi_attr_t_info.slave_num = 1;

    spi_extra_attr_t spi_cfg_extra_info = {0};
    hal_spi_xfer_qspi_param_t qspi_param = {0};
    hal_spi_xfer_sspi_param_t sspi_param = {0};
    sspi_param.wait_cycles = 0; // 设置sspi的等待周期
    qspi_param.trans_type = 0;  // 标准 SPI
    qspi_param.inst_len = 0;    // 指令长度
    qspi_param.addr_len = 0;    // 地址长度
    qspi_param.wait_cycles = 0;

    spi_cfg_extra_info.qspi_param = qspi_param;
    spi_cfg_extra_info.rx_use_dma = 0;
    spi_cfg_extra_info.tx_use_dma = 0;
    spi_cfg_extra_info.sspi_param = sspi_param;

    int ret = uapi_spi_init(SPI_BUS_0, &spi_attr_t_info, &spi_cfg_extra_info);
    if (ret != 0)
    {
        printf("SPI 初始化失败！\n");
    }
    else
    {
        printf("SPI 初始化成功。\n");
    }
}

errcode_t usr_spi_writeread(uint8_t *wdata, uint8_t wlen, uint8_t *rdata, uint8_t rlen)
{
    spi_xfer_data_t spi_recv_xfer = {0};
    spi_recv_xfer.tx_buff = wdata;                                   // 设置 tx buff
    spi_recv_xfer.tx_bytes = wlen;                                   // 设置 tx buff 长度
    spi_recv_xfer.rx_buff = rdata;                                   // 设置 rx buff
    spi_recv_xfer.rx_bytes = rlen;                                   // 设置 rx buff 长度
    spi_porting_set_rx_mode(SPI_BUS_0, rlen);                        // 设置 写读接口的 rx 接收模式
    errcode_t ret = uapi_spi_master_writeread(SPI_BUS_0, &spi_recv_xfer, 100);       // 读取数据
        if (ret != ERRCODE_SUCC)
    {
        printf("SPI 发送失败，错误码：%d\n", ret);
        // 根据需要处理错误，例如重试、报警等
    }
    else
    {
        printf("SPI 发送成功。\n");
        // 继续后续处理
    }

    return ret;
}

errcode_t usr_spi_write(uint8_t *wdata, uint8_t wlen)
{
    spi_xfer_data_t spi_send_xfer = {0};
    spi_send_xfer.tx_buff = wdata;    // 设置发送缓冲区
    spi_send_xfer.tx_bytes = wlen;    // 设置发送字节数
    spi_send_xfer.rx_buff = NULL;     // 不接收数据
    spi_send_xfer.rx_bytes = 0;       // 接收字节数为 0

    errcode_t ret = uapi_spi_master_write(SPI_BUS_0, &spi_send_xfer, 100); // 发送数据
    if (ret != ERRCODE_SUCC)
    {
        printf("SPI 发送失败，错误码：%d\n", ret);
        // 根据需要处理错误，例如重试、报警等
    }
    else
    {
        printf("SPI 发送成功。\n");
        // 继续后续处理
    }

    return ret;
}

void usr_spi_read(uint8_t *rdata, uint8_t rlen)
{
    spi_xfer_data_t spi_recv_xfer = {0};
    spi_recv_xfer.tx_buff = NULL;     // 不发送数据
    spi_recv_xfer.tx_bytes = 0;       // 发送字节数为 0
    spi_recv_xfer.rx_buff = rdata;    // 设置接收缓冲区
    spi_recv_xfer.rx_bytes = rlen;    // 设置接收字节数

    spi_porting_set_rx_mode(SPI_BUS_0, rlen); // 设置接收模式
    uapi_spi_master_read(SPI_BUS_0, &spi_recv_xfer, 100); // 接收数据
}